package com.cgnpc.scp.sri.budget.service.impl;

import cn.com.cgnpc.aep.bizcenter.appcenter.sdk.result.ApiResult;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cgnpc.cud.core.domain.AjaxResult;
import com.cgnpc.cuddemo.utils.IDHelper;
import com.cgnpc.framework.service.IBpmCenterService;
import com.cgnpc.framework.userinfo.CurrentUser;
import com.cgnpc.scp.common.bean.CreateFileInfo;
import com.cgnpc.scp.common.bean.MyPageResult;
import com.cgnpc.scp.common.exception.ScpException;
import com.cgnpc.scp.common.service.AppConstantService;
import com.cgnpc.scp.common.utils.BpmUtil;
import com.cgnpc.scp.common.utils.MyPageResultUtil;
import com.cgnpc.scp.common.utils.StringUtil;
import com.cgnpc.scp.run.utils.CommonExportUtil;
import com.cgnpc.scp.sri.budget.mybatis.entity.*;
import com.cgnpc.scp.sri.budget.mybatis.mapper.client.BudgetItemMapper;
import com.cgnpc.scp.sri.budget.mybatis.mapper.client.BudgetItemTripPeopleMapper;
import com.cgnpc.scp.sri.budget.pojo.Expense;
import com.cgnpc.scp.sri.budget.service.BudgetInfoService;
import com.cgnpc.scp.sri.budget.service.BudgetItemService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.ibatis.session.SqlSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;

@Service("budgetItemService")
public class BudgetItemServiceImpl implements BudgetItemService {
    private final static Logger LOGGER = LoggerFactory.getLogger(BudgetItemServiceImpl.class);

    @Autowired
    private BudgetItemMapper budgetItemMapper;

    @Autowired
    private BudgetItemTripPeopleMapper budgetItemTripPeopleMapper;

    @Autowired
    private BudgetInfoService budgetInfoService;

    @Autowired
    private CurrentUser currentUser;

    @Autowired
    IBpmCenterService bpmCenterService;

    @Autowired
    private AppConstantService appConstantService;

    @Autowired
    private SqlSession sqlSession;

    @Override
    public MyPageResult<BudgetItem> queryListPage(Map<String, Object> params) {
        MyPageResult<BudgetItem> re = null;
        int pageNum = 1;
        int pageSize = 10;
        try {
            pageNum = Integer.parseInt(params.get("pageNum") + "");
            pageSize = Integer.parseInt(params.get("pageSize") + "");
        }catch (Exception e){
            e.printStackTrace();
        }
        Page<BudgetItem> queryPage = PageHelper.startPage(pageNum, pageSize);
        budgetItemMapper.listPage(params);
        PageInfo<BudgetItem> pageResult = new PageInfo<>(queryPage.getResult());
        re = MyPageResultUtil.createMyPageResult(pageResult);

        return re;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult saveBudgetItem(Map<String, Object> params) throws Exception {
        Map<String, Object> budgetItemMap = (Map<String, Object>)params.get("budgetItem");
        BudgetItem budgetItem = (BudgetItem) BpmUtil.mapToObjectByJson(budgetItemMap, BudgetItem.class);
        String itemId = budgetItem.getId();
        Date date = new Date();
        budgetItem.setLastUpdateTime(date);
        budgetItem.setLastUpdateUser(currentUser.getCurrentUserDetail().getUserId());
        budgetItem.setLastUpdateUserName(currentUser.getCurrentUserDetail().getUserName());
        Date createTime = budgetItem.getCreateTime() == null ? date : budgetItem.getCreateTime();
        String folio = budgetItem.getProcessName() + "-" + budgetItem.getCreateUser() + "-" +
                new SimpleDateFormat("yyyyMMdd").format(createTime);
        if(StringUtil.isNullOrSpace(itemId)){
            budgetItem.setCreateTime(date);
            budgetItem.setCreateUser(currentUser.getCurrentUserDetail().getUserId());
            budgetItem.setCreateUserName(currentUser.getCurrentUserDetail().getUserName());
            budgetItem.setId(IDHelper.uuid());
            budgetItem.setFolio(folio);
        }
        if("1".equals(params.get("isSaveDraft"))){
            //存草稿的情况
            budgetItem.setProcessStatus("2");
            if("1".equals(params.get("isModifyDraft"))){
                //修改草稿的情况
                saveOrUpdateTripPerson(budgetItem);
                budgetItemMapper.updateById(budgetItem);
                return AjaxResult.success().put("data", budgetItem);
            }
        }

        budgetItemMapper.insert(budgetItem);
        saveOrUpdateTripPerson(budgetItem);

        params.put("next_deal_name", JSONArray.parseArray(JSON.toJSONString(params.remove("next_deal_name"))));
        params.put("win", JSON.parseObject(JSON.toJSONString(budgetItemMap)));
        params.put("folio", folio);
        ApiResult apiResult = null;
        //判断是否为保存草稿
        params.put("appFormId", budgetItem.getId());
//        params.put("procChName", budgetItem.getFolio());
        if("1".equals(params.get("isSaveDraft"))){
            bpmCenterService.addDraft(params);
        }else{

            apiResult = bpmCenterService.startProcess(params);
            //System.out.println("result--" +apiResult);
        }
        return AjaxResult.success().put("data", budgetItem);
    }

    @Override
    public CreateFileInfo exportExcel(Map<String, Object> params) throws Exception {
        final String logInfo = "[exportExcel_UUID_" + UUID.randomUUID() + "]";
        CreateFileInfo createFileInfo = null;

        try {
            List<String> titleList = Arrays.asList(
                    "预算年度","课题编码","课题名称","所在分部","出差事由"
                    ,"差旅费","会议费","咨询费","业务支持费"
                    ,"设备费","软件费","申请总额"
            );
            List<String> fields = Arrays.asList("year","subjectCode","subjectName","belongSubsectionLabel","tripReason"
                    ,"travelExpense","meetingExpense","consultingExpense","businessSupportExpense"
                    ,"deviceExpense","softwareExpense","totalExpense"
            );

            CommonExportUtil<BudgetItem> util = new CommonExportUtil<>();
            createFileInfo = util.exportExcel(appConstantService, sqlSession, titleList, fields
                    , "com.cgnpc.scp.sri.budget.mybatis.mapper.client.BudgetItemMapper"
                    ,"listPageExport", params);
        } catch (Exception e) {
            LOGGER.error("{}error;", logInfo, e);
            throw e;
        }

        return createFileInfo;
    }

    @Override
    public BudgetItem getItemById(String id) {
        if(StringUtil.isNullOrSpace(id)){
            throw  new ScpException("id can not be null");
        }
        BudgetItem result = budgetItemMapper.selectById(id);
        Expense left = budgetInfoService.getLeftByYear(result.getYear() + "");
        result.setLeft(left);

        List<BudgetItemTripPeople> tripPeople = budgetItemTripPeopleMapper.selectList(new QueryWrapper<BudgetItemTripPeople>()
        .eq("budget_item_id", result.getId()));
        result.setTripPerson(tripPeople);

        return result;
    }

    /**********************************
     * 用途说明: 审批操作（通过或驳回）
     * 参数说明 params
     * 返回值说明:
     ***********************************/
    @Override
    @Transactional
    public ApiResult submitProcess(Map<String, Object> params) throws Exception {
        // 流程除了启动环节，任意环节提交时均要保存流程实例id
        String procInstId = params.get("procInstId").toString();
        if (StringUtil.isNullOrSpace(procInstId)) {
            throw new ScpException("procInstId is missing.");
        }
        //判断是前进还是后退
        String flag = params.get("deal_answer").toString();
        ApiResult apiResult = null;
        // 根据环节名称判断当前处理逻辑
        String act_name = params.get("now_deal_act").toString();
        String formInstID = params.get("formInstID").toString();
        params.put("next_deal_name",JSONArray.parseArray(JSON.toJSONString(params.remove("next_deal_name"))));
        Object copygive = params.remove("copygive");
        if(copygive != null && !"".equals(copygive)){
            params.put("copygive",JSONArray.parseArray(JSON.toJSONString(copygive)));
        }
        if (!StringUtil.isNullOrSpace(act_name) && ("020".equals(act_name)||"010".equals(act_name))) {
            if ("1".equals(flag)) {
                //提交
                BudgetItem budgetItem = new BudgetItem();
                budgetItem.setProcInstId(procInstId);
                if("020".equals(act_name)){
                    //（此时需要将预算申请的条目显示）
                    budgetItem.setProcessStatus("1");
                }

                budgetItem.setId(formInstID);
                budgetItemMapper.updateById(budgetItem);

                apiResult = bpmCenterService.submitworklistitem(params);
//                processAudit(params);
            } else if ("2".equals(flag)) {
                //驳回
                apiResult = bpmCenterService.rollBackAction(params);
            }
        } else {
            throw new ScpException("activity not found.");
        }
        return apiResult;
    }

    @Override
    public ApiResult deleteDraft(Map<String, Object> params) throws Exception {
        String itemId = params.get("formno").toString();
        budgetItemMapper.deleteById(itemId);

        return bpmCenterService.deleteMyDraft(params);
    }

    private void saveOrUpdateTripPerson(BudgetItem budgetItem){

        budgetItemTripPeopleMapper.delete(new QueryWrapper<BudgetItemTripPeople>()
                .eq("budget_item_id", budgetItem.getId()));
        List<BudgetItemTripPeople> tripPeople = budgetItem.getTripPerson();
        if(tripPeople != null && tripPeople.size() != 0){
            for(BudgetItemTripPeople people : tripPeople){
                people.setId(IDHelper.uuid());
                people.setBudgetItemId(budgetItem.getId());
                budgetItemTripPeopleMapper.insert(people);
            }
        }
    }
}
